﻿// SyntheticDataGenerator.Generators.ExponentialGenerator
//
// (c) 2011 Arthur Pitman
//
// Part of Market-Basket Synthetic Data Generator
// A C# adaptation of the IBM Quest Market-Basket Synthetic Data Generator
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// (Version 2) as published by the Free Software Foundation.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License (Version 2) along with this program; if not, write to 
// the Free Software Foundation, Inc., 
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// or see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SyntheticDataGenerator.Generators
{
	/// <summary>
	/// Generates random numbers with an exponential distribution
	/// 
	/// See "Numerical Recipes in C: The Art of Scientific Computing" by Press et al.
	/// </summary>
	public class ExponentialGenerator : IGenerator
	{
		/// <summary>
		/// The mean of the distribution
		/// </summary>
		protected double mean;

		/// <summary>
		/// The <see cref="UniformGenerator"/> used for randomness
		/// </summary>
		protected UniformGenerator uniformGenerator = new UniformGenerator();

		/// <summary>
		/// Initializes a new <see cref="ExponentialGenerator"/> instance with the specified mean
		/// </summary>
		/// <param name="mean">The mean of the distribution</param>
		public ExponentialGenerator(double mean = 1.0)
		{
			this.mean = mean;
		}    

		/// <summary>
		/// Returns a random variable with an exponential distribution
		/// </summary>
		/// <returns>The random variable</returns>
		public double Next()	
		{
			double x = 0;
			do
			{
				x = uniformGenerator.Next();
			}
			while (x == 0.0);
			return mean * -Math.Log(x);            
		}

	}
}
